<template>
  <div>
    <!-- 人际关系图 -->
    <p class="legend-box">
      <span><i></i>机构</span>
      <span><i></i>企业</span>
      <span><i></i>人物</span>
    </p>
    <div id="chartFour"></div>
    <!-- 提示框 -->
    <div class="g6-tooltip tooltip-box" :style="{top: clientY + 'px', left: clientX + 'px'}" @mouseenter="tooltipMouseEnter" @mouseleave="tooltipMouseLeave">
      <template v-if="showTooltip==='node'">
        <div class="tip-box">{{toolTipNodeModel && toolTipNodeModel.label}}</div>
      </template>
      <template v-else-if="showTooltip==='edge'">
        <ul class="list-box" :class="{maxHeight: this.ipi>1}">
          <li class="theader">
            <span>申请日</span>
            <span>专利号</span>
            <span>科研成果</span>
          </li>
          <li v-for="(item, index) in toolTipEdgeModel" :key="index" class="tbody">
            <span>{{item.ad}}</span>
            <span>{{item.pn}}</span>
            <span>{{item.title}}</span>
          </li>
        </ul>
        <el-pagination
          background
          layout="prev, pager, next"
          :total="total"
          :page-size="ips"
          :current-page.sync="ipi"
          @current-change="getCurrentPage"
          class="elpagination">
        </el-pagination>
      </template>
      
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      info: {},
      graph: null,
      chartData: {
        nodes: [],
        edges: []
      },
      scrollWidth: 0,
      scrollHeight: 0,
      rootNodeWidth: 109,
      rootNodeHeight: 109,
      ipi: 1,
      ips: 6,
      total: 0,
      showTooltip: false,
      toolTipHidden: false,
      toolTipHiddenTimeout: null,
      clientX: -9999,
      clientY: -9999,
      toolTipNodeModel: {},
      toolTipEdgeModel: [],
      toolTipEdgeAllModel: []
    }
  },
  methods: {
    init() {
      this.info = {
        name: this.$route.query.name,
        key: this.$route.query.key,
        companyName: this.$route.query.companyName
      }
      this.scrollWidth = document.getElementById('chartFour').scrollWidth
      this.scrollHeight = document.getElementById('chartFour').scrollHeight
      this.initrG6()
    },
    // 自定义节点
    initrG6() {
      // 中心节点
      G6.registerNode('rootNode', {
        draw(cfg, group) {
          const width = 109
          const height = 109
          const mWidth = 55
          const mHeight = 55
          const style = cfg.style

          const keyShape = group.addShape('circle', {
            attrs: {
              ...style,
              x: width / 2,
              y: height / 2,
              r: width / 2
            },
            name: 'rootKeyShape',
            draggable: true
          })

          const circleImg1 = group.addShape('image', {
            attrs: {
              width,
              height,
              img: ''
            },
            name: 'circleImg1',
            draggable: true
          })

          const circleImg2 = group.addShape('image', {
            attrs: {
              width: mWidth,
              height: mHeight,
              x: (width - mWidth) / 2,
              y: (height - mHeight) / 2,
              img: ''
            },
            name: 'circleImg2',
            draggable: true
          })

          const content = cfg.label && cfg.label.length > 12 ? cfg.label.substr(0, 10) + '...' : cfg.label
          const text = group.addShape('text', {
            attrs: {
              textAlign: 'center',
              textBaseline: 'top',
              text: content,
              x: width / 2,
              y: height + 10,
              fill: '#2f41c8',
              fontSize: 22,
              fontWeight: 'bold',
              textAlign: 'center',
              lineHeight: 20
            },
            name: 'rootTextShape',
            draggable: true
          })

          return keyShape
        }
      }, 'circle')

      // 子节点
      G6.registerNode('childNode', {
        draw(cfg, group) {
          let width = 31
          let height = 31
          const style = cfg.style

          let imgData = ''
          if (cfg.dataType === '机构') { // 机构
            imgData = ''
          } else if (cfg.dataType === '企业') { // 企业
            imgData = ''
          } else if (cfg.dataType === '人物') { // 人物
            width = 20
            height = 20
            imgData = ''
          }

          const keyShape = group.addShape('circle', {
            attrs: {
              ...style,
              x: width / 2,
              y: height / 2,
            },
            name: 'childNodeKeyShape',
            draggable: true
          })

          // 公司图标
          const circleImg1 = group.addShape('image', {
            attrs: {
              width,
              height,
              img: imgData
            },
            name: 'circleImg1',
            draggable: true
          })

          let content = cfg.label && cfg.label.length > 12 ? cfg.label.substr(0, 10) + '...' : cfg.label
          let text1Y = height + 10
          const text1 = group.addShape('text', {
            attrs: {
              textAlign: 'center',
              textBaseline: 'top',
              text: content,
              x: width / 2,
              y: text1Y,
              fill: '#373275',
              fontSize: 14,
              textAlign: 'center',
              lineHeight: 16
            },
            name: 'childNodeTextShape1',
            draggable: true
          })

          return keyShape
        },
      }, 'circle')

      // 连线
      G6.registerEdge('flowLine', {
        // 响应状态变化
        setState(name, value, item) {
          const group = item.getContainer();
          const shape = group.get('children')[0]; // 顺序根据 draw 时确定
          if (value) {
            shape.attr({
              lineWidth: 3,
              stroke: '#405bda'
            })
          } else {
            shape.attr({
              lineWidth: 3,
              stroke: '#c8c4e6'
            })
          }
        },
        // update这里的设置非常重要，必须要写
        update: undefined
      }, 'line')
    },
    getChartData() {
      this.$post(this.$Url.team.talentsCooperate, {
        musts: {
          date_sort: '1',
          'in2id.id': this.info.key
        },
        aggs: [
          {
            type: 'base',
            size: '50',
            field: 'an'
          },
          {
            type: 'base',
            size: '50',
            field: 'in2id.name'
          }
        ]
      }).then(res => {
        let data = res.data
        let nodes = [
          // 中心节点
          {
            id: this.info.name,
            label: this.info.name,
            type: 'rootNode',
            x: (this.scrollWidth - this.rootNodeWidth) / 2,
            y: (this.scrollHeight - this.rootNodeHeight) / 2
          },
          // 任职
          {
            id: data.job.key,
            label: data.job.key,
            type: 'childNode',
            dataType: data.job.type
          },
        ]

        let edges = [
          {
            source: this.info.name,
            target: data.job.key,
            targetType: data.job.type,
            label: '任职',
          }
        ]

        data.cooperation.forEach((v, index) => {
          nodes.push({
            id: v.key,
            label: v.key,
            type: 'childNode',
            dataType: v.type,
          })
          if (v.key !== this.info.name) {
            edges.push({
              source: this.info.name,
              target: v.key,
              targetType: v.type,
              label: '合作'
            })
          }
        })

        let chartData = {
          nodes,
          edges
        }
        this.renderChart(chartData)
      }).catch(err => {})
    },
    renderChart(chartData) {
      let graph = new G6.Graph({
        container: 'chartFour',
        width: this.scrollWidth,
        height: this.scrollHeight,
        layout: {
          // type: 'random',
          type: 'force',
          // center: [(this.scrollWidth - this.rootNodeWidth) / 2, (this.scrollHeight - this.rootNodeHeight) / 2],
          // center: [chartData.nodes[0].x + this.rootNodeWidth / 2, chartData.nodes[0].y + 40],
          preventOverlap: true,
          // collideStrength: 1,
          nodeSize: [109, 60],
          // nodeStrength: -10,
          linkDistance: (param) => {
            // let x = param.target.x
            // let y = param.target.y
            let distance = this.scrollHeight / 3
            // if (x <= this.scrollWidth / 3 || x >= this.scrollWidth * (2/3)) {
            //   distance = this.scrollHeight / 3 + 50
            // }
            return distance
          },
          // linkDistance: 50,         // 可选，边长
          // nodeStrength: 30,         // 可选
          // edgeStrength: 0.1,        // 可选
          // collideStrength: 0.8,     // 可选
          // nodeSize: 30,             // 可选
          // alpha: 0.3,               // 可选
          // alphaDecay: 0.028,        // 可选
          // alphaMin: 0.01,           // 可选
          forceSimulation: null,    // 可选
          onTick: () => {           // 可选
            // graph.refreshPositions()
            // console.log('ticking');
          },
          onLayoutEnd: () => {      // 可选
            // console.log('force layout done');
          },
          workerEnabled: true,
          gpuEnabled: true
        },

        // plugins: [tooltip],
        // layout: {
        //   type: 'force',
        //   linkDistance: (param) => {
        //     let x = param.target.x
        //     let y = param.target.y
        //     let distance = 280
        //     // if (x <= this.scrollWidth / 3 || x >= this.scrollWidth * (2/3)) {
        //     //   distance = 450
        //     // }
        //     return distance
        //   },
        //   // linkDistance: 100,
        //   nodeSize: [109, 60],
        //   preventOverlap: true,
        //   // clustering: true,
        //   // type: 'fruchterman',
        //   // gravity: 10,
        //   // speed: 10,
        //   // clustering: true,
        //   // clusterGravity: 50,
        //   // gravity: 1,              // 可选
        //   // speed: 5,                 // 可选
        //   // clustering: false,         // 可选
        //   // clusterGravity: 10,       // 可选
        //   // maxIteration: 2000,       // 可选，迭代次数
        //   // workerEnabled: true       // 可选，开启 web-worker  }
        // },
        modes: {
          default: [
            'drag-canvas', 
            'drag-node', 
            // 'zoom-canvas',
          ]
        },
        defaultNode: {
          type: 'rootNode'
        },
        defaultEdge: {
          type: 'flowLine',
          style: {
            lineWidth: 2,
            lineAppendWidth: 3,
            stroke: '#c8c4e6',
            lineDash: [3],
          },
          labelCfg: {
            autoRotate: false,
            style: {
              fontWeight: 'normal',
              fontSize: 12
            }
          }
        },
        animate: false
      })
      
      graph.read(chartData)

      this.graph = graph

      // node事件
      graph.on('node:mouseenter', (ev) => {
        const node = ev.item
        const model = node.getModel()
        this.clientX = ev.x
        this.clientY = ev.y
        
        this.toolTipNodeModel = model
        this.showTooltip = 'node'
        this.toolTipHidden = false
      })

      graph.on('node:mousemove', (ev) => {
        this.clientX = ev.x
        this.clientY = ev.y
      })

      graph.on('node:mouseleave', (ev) => {
        this.toolTipHidden = true
      })

      // edge事件
      graph.on('edge:mouseenter', (ev) => {
        const edge = ev.item
        const model = edge.getModel()
        let name = 'color' + model.dataType
        graph.setItemState(edge, name, true)

        this.ipi = 1

        if (!model.result) {
          this.getTalentsCooperateList(model, (result) => {
            model.result = result
            this.toolTipEdgeAllModel = result
            this.toolTipEdgeModel = result.slice(0, this.ipi * this.ips)
            this.total = result.length
          })
        } else {
          this.toolTipEdgeAllModel = model.result
          this.toolTipEdgeModel = model.result.slice(0, this.ipi * this.ips)
          this.total = model.result.length
        }

        this.clientX = ev.x
        this.clientY = ev.y

        this.showTooltip = 'edge'
        this.toolTipHidden = false
      })

      graph.on('edge:mousemove', ev => {
        this.clientX = ev.x
        this.clientY = ev.y
      })

      graph.on('edge:mouseleave', (ev) => {
        const edge = ev.item
        const model = edge.getModel()
        let name = 'color' + model.dataType
        graph.setItemState(edge, name, false)
        
        this.toolTipHidden = true
      })

    },
    // 获取关系
    getTalentsCooperateList(model, func) {
      let type = model.targetType
      let param = {
        musts: {
          date_sort: '1',
          'in2id.id': this.info.key
        },
        source: ['ad', 'title', 'pn']
      }

      if (type !== '人物') {
        param['musts']['an'] = model.target
      } else {
        param['musts']['in2id.name'] = model.target
      }

      this.$post(this.$Url.team.talentsCooperateList, param).then(res => {
        let data = res.data
        let result = (data && data.result) || []
        func && func(result)
      }).catch(err => {})

    },
    getCurrentPage(val) {
      this.ipi = val
      this.toolTipEdgeModel = this.toolTipEdgeAllModel.slice((this.ipi - 1) * this.ips, this.ipi * this.ips)
    },
    tooltipMouseEnter(e) {

    },
    tooltipMouseLeave(e) {

    }
  },
  watch: {
    toolTipHidden() {
      if (this.toolTipHidden) {
        if (this.toolTipHiddenTimeout) {
          clearTimeout(this.toolTipHiddenTimeout)
          this.toolTipHiddenTimeout = null
        } else {
          this.toolTipHiddenTimeout = setTimeout(() => {
            this.showTooltip = false
            this.toolTipHidden = false
            this.toolTipHiddenTimeout = null
          }, 300)
        }
      } else {
        if (this.toolTipHiddenTimeout) {
          clearTimeout(this.toolTipHiddenTimeout)
          this.toolTipHiddenTimeout = null
        }
      }
    }
  },
  mounted() {
    this.init()
    this.getChartData()
  }
}
</script>

<style lang="scss" scoped>
#chartFour {
  width: 100%;
  height: 650px;
}
.legend-box {
  position: relative;
  display: inline-block;
  margin-left: 23px;
  span {
    display: inline-flex;
    margin-right: 50px;
    font-size: 14px;
    color: $mainColor;
    &:nth-child(1) {
      i {
        background-image: url('');
      }
    }
    &:nth-child(2) {
      i {
        background-image: url('');
      }
    }
    &:nth-child(3) {
      i {
        background-image: url('');
      }
    }
    i {
      display: block;
      width: 20px;
      height: 20px;
      margin-right: 20px;
      background-position: center center;
      background-size: 100% 100%;
      background-repeat: no-repeat;
    }
  }
}

.list-box {
  position: relative;
  width: 650px;
  padding: 0 21px;
  &.maxHeight {
    height: 309px;
  }
  li {
    position: relative;
    display: flex;
    // padding: 0 22px;
    list-style: none;
    color: #7674a3;
    span {
      flex: 1;
      padding-left: 4px;
      padding-right: 4px;
      font-size: 14px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
  .theader {
    line-height: 44px;
    border-bottom: 1px solid #f0f0fb;
    span {
      font-weight: bold;
      color: #2d3a86;
    }
  }
  .tbody {
    line-height: 18px;
    padding-top: 13px;
    padding-bottom: 13px;
    // &:hover {
    //   box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
    //   color: $mainColor;
    //   cursor: pointer;
    // }
  }
}
.elpagination {
  margin-top: 10px;
  margin-bottom: 10px;
  text-align: center;
}
</style>